//package org.bdware.doip.core.crypto;
//
//import com.nimbusds.jose.*;
//import com.nimbusds.jose.crypto.*;
//import com.nimbusds.jose.jwk.JWK;
//import com.nimbusds.jose.jwk.KeyType;
//import org.apache.log4j.Logger;
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
//
//import java.security.Security;
//import java.text.ParseException;
//
//public class CertUtils {
//
//    static Logger logger = Logger.getLogger(org.bdware.irp.crypto.CertUtils.class);
//    static ByteStringCodec codec;
//
//    static {
//        Security.addProvider(new BouncyCastleProvider());
//    }
//
//    public static void setKeysCodec(ByteStringCodec c){
//        codec = c;
//    }
//
//    public static String Sign(byte[] data, JWK jwk) throws Exception {
//        JWSSigner jwsSigner;
//        JWSObject jwsObject;
//
//        if(jwk.getKeyType() == KeyType.RSA){
//            jwsSigner = new RSASSASigner(jwk.toRSAKey());
//            jwsObject = new JWSObject(
//                    new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(jwk.getKeyID()).build(),
//                    new Payload(data));
//        }else if(jwk.getKeyType() == KeyType.EC){
//            jwsSigner = new ECDSASigner(jwk.toECKey());
//            // Creates the JWS object with payload
//            jwsObject = new JWSObject(
//                    new JWSHeader.Builder(JWSAlgorithm.ES256).keyID(jwk.getKeyID()).build(),
//                    new Payload(data));
//        }else{
//            logger.error("unsupported Algorithm");
//            return null;
//        }
//        // Compute the EC signature
//        jwsObject.sign(jwsSigner);
//        // Serialize the JWS to compact form
//        String s = jwsObject.serialize(true);
//        return s;
//    }
//
//    public static boolean verify(byte[] payload, String jws, JWK pkToVerify) throws Exception {
//        JWSObject signature = JWSObject.parse(jws,new Payload(payload));
//        JWSVerifier verifier;
//        if(pkToVerify.getKeyType() == KeyType.RSA){
//            verifier = new RSASSAVerifier(pkToVerify.toRSAKey().toRSAPublicKey());
//        }else if(pkToVerify.getKeyType() == KeyType.EC){
//            verifier = new ECDSAVerifier(pkToVerify.toECKey().toECPublicKey());
//        }else{
//            logger.error("unsupported Algorithm");
//            return false;
//        }
//        return signature.verify(verifier);
//    }
//
//    public static byte[] encrypt(byte[] payload, JWK pkToEncrypt) throws JOSEException {
//        JWEAlgorithm alg;
//        EncryptionMethod enc = EncryptionMethod.A256GCM;
//        JWEObject jweObject;
//        if(pkToEncrypt.getKeyType() == KeyType.RSA){
//            alg = JWEAlgorithm.RSA_OAEP_256;
//            jweObject= new JWEObject(
//                    new JWEHeader(alg,enc),
//                    new Payload(payload)
//            );
//            jweObject.encrypt(new RSAEncrypter(pkToEncrypt.toRSAKey().toRSAPublicKey()));
//        }else if(pkToEncrypt.getKeyType() == KeyType.EC){
//            alg = JWEAlgorithm.ECDH_ES;
//            jweObject= new JWEObject(
//                    new JWEHeader(alg,enc),
//                    new Payload(payload)
//            );
//            jweObject.encrypt(new ECDHEncrypter(pkToEncrypt.toECKey().toECPublicKey()));
//        }else{
//            throw new JOSEException("only support RSA or EC key");
//        }
//        return jweObject.serialize().getBytes();
//    }
//
//    public static byte[] decrypt(byte[] cipherText, JWK skToDecrypt) throws ParseException, JOSEException {
//        JWEObject decrypt = JWEObject.parse(new String(cipherText));
//        if(skToDecrypt.getKeyType() == KeyType.RSA){
//            decrypt.decrypt(new RSADecrypter(skToDecrypt.toRSAKey().toRSAPrivateKey()));
//        }else if(skToDecrypt.getKeyType() == KeyType.EC){
//            decrypt.decrypt(new ECDHDecrypter(skToDecrypt.toECKey().toECPrivateKey()));
//        }else{
//            throw new JOSEException("only support RSA or EC key");
//        }
//                return decrypt.getPayload().toBytes();
//    }
//
////
////    public static String encodeKey(Key publicKey) {
////        if(codec == null) codec = new Base64JavaUtilsImpl();
////        return codec.encodeToString(publicKey.getEncoded());
////    }
////
////    public static PublicKey decodePublicKey(String pkStr, String pkAlgorithm) throws Exception {
////        if(codec == null) codec = new Base64JavaUtilsImpl();
////        X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(codec.decodeFromString(pkStr));
////        KeyFactory keyFactory = KeyFactory.getInstance(pkAlgorithm);
////        return keyFactory.generatePublic(bobPubKeySpec);
////    }
////
////    public static PrivateKey decodePrivateKey(String skStr, String pkAlgorithm) throws Exception {
////        if(codec == null) codec = new Base64JavaUtilsImpl();
////        PKCS8EncodedKeySpec bobPubKeySpec = new PKCS8EncodedKeySpec(codec.decodeFromString((skStr)));
////        KeyFactory keyFactory = KeyFactory.getInstance(pkAlgorithm);
////        return keyFactory.generatePrivate(bobPubKeySpec);
////    }
////
////    public static byte[] encrypt(byte[] input, PublicKey publicKey) throws Exception {
////        Cipher c = Cipher.getInstance(publicKey.getAlgorithm());
////        c.init(Cipher.ENCRYPT_MODE,publicKey);
////
////        byte[] cypherBytes = new byte[0];
////        int pos = 0;
////
////        while(pos < input.length){
////            int segLen = Math.min(input.length-pos, 245);
////            byte[] encSeg = new byte[segLen];
////            System.arraycopy(input,pos,encSeg,0,segLen);
////            cypherBytes = concat(cypherBytes,c.doFinal(encSeg));
////            pos += segLen;
////        }
////        return cypherBytes;
////    }
////
////    public static byte[] decrypt(byte[] input, PrivateKey privateKey) throws Exception{
////        Cipher c = Cipher.getInstance(privateKey.getAlgorithm());
////        c.init(Cipher.DECRYPT_MODE,privateKey);
////
////        byte[] rawBytes = new byte[0];
////        int pos = 0;
////        while(pos < input.length){
////            int segLen = Math.min(input.length-pos, 256);
////            byte[] encSeg = new byte[segLen];
////            System.arraycopy(input,pos,encSeg,0,segLen);
////            rawBytes = concat(rawBytes,c.doFinal(encSeg));
////            pos += segLen;
////        }
////        return rawBytes;
////    }
////
////    private static byte[] concat(byte[] bytes1, byte[] bytes2){
////        byte[] result = new byte[bytes1.length + bytes2.length];
////        System.arraycopy(bytes1, 0, result, 0, bytes1.length);
////        System.arraycopy(bytes2, 0, result, bytes1.length, bytes2.length);
////        return result;
////    }
//}
